package com.richard.library.http.interceptor;


import android.util.Log;

import androidx.annotation.NonNull;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Locale;

import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okio.Buffer;

/**
 * <pre>
 * Description : 日志打印 拦截器
 * Author : admin-richard
 * Date : 2016/12/19 15:46
 * Changelog:
 * Version            Date            Author              Detail
 * ----------------------------------------------------------------------
 * 1.0         2016/12/19 15:46     admin-richard         new file.
 * </pre>
 */
public class LogInterceptor implements Interceptor {

    private final String TAG = "http_log";

    @NonNull
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        RequestBody requestBody = request.body();

        Buffer buffer = new Buffer();
        MediaType contentType = null;
        Charset charset = null;
        boolean isUploadFileType = false;

        if (requestBody != null) {
            contentType = requestBody.contentType();
        }

        if (contentType != null) {
            charset = contentType.charset(StandardCharsets.UTF_8);
            isUploadFileType = "multipart".equalsIgnoreCase(contentType.type()) && "form-data".equalsIgnoreCase(contentType.subtype());
        }

        if (charset == null) {
            charset = StandardCharsets.UTF_8;
        }

        if (!isUploadFileType && requestBody != null) {
            requestBody.writeTo(buffer);
        }

        //请求参数报文
        String json = buffer.readString(charset);
        try {
            json = URLDecoder.decode(json, "UTF-8");
        } catch (Throwable ignored) {
        }

        String requestParams =
                isUploadFileType
                        ? "文件二进制数据不打印请求参数日志"
                        : this.formatJson(json);

        Log.d(TAG,String.format(
                "%s\n\nRequest{method=%s, url=%s}\n\n%s\n\n%s\n%s\n%s\n\n%s\n\n"
                , "------------------------请求URL------------------------"
                , request.method()
                , request.url()
                , "------------------------请求头信息----------------------"
                , String.format("%s%s", contentType == null ? "" : "Content-Type: ".concat(contentType.toString()), request.headers())
                , String.format("%s", requestBody == null ? "" : "Content-Length: ".concat(String.valueOf(requestBody.contentLength())))
                , "\n------------------------请求参数------------------------"
                , String.format("%s\n ", requestParams)
        ));

        long t1 = System.nanoTime();
        Response response = chain.proceed(chain.request());
        long t2 = System.nanoTime();

        MediaType mediaType = response.body() == null ? null : response.body().contentType();
        String content = response.body() == null ? "" : response.body().string();

        Log.d(TAG,String.format(
                "\n%s\n\n%s\n\n%s\n\n%s\n\n%s\n%s\n\n%s\n\n"
                , "------------------------响应状态信息---------------------"
                , String.format(
                        Locale.getDefault()
                        , "Response{code=%s, isRedirect=%s, time=%.1fms, url=%s}"
                        , response.code()
                        , response.isRedirect()
                        , (t2 - t1) / 1e6d
                        , response.request().url()
                )
                , String.format("请求参数(该段日志非云端返回) : \n%s", requestParams)
                , "------------------------响应头信息----------------------"
                , response.headers()
                , "------------------------响应数据------------------------"
                , this.formatJson(content)
        ));

        if (mediaType == null) {
            return response.newBuilder()
                    .build();
        }

        return response.newBuilder()
                .body(okhttp3.ResponseBody.create(mediaType, content))
                .build();
    }


    private  String formatJson(String json) {
        try {
            if (json.startsWith("{") && json.endsWith("}")) {
                json = new JSONObject(json).toString(4);
            } else if (json.startsWith("[") && json.endsWith("]")) {
                json = new JSONArray(json).toString(4);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return json;
    }
}
